﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using Perspective.Wpf3D.Primitives;
using Perspective.Wpf3D.Sculptors;

namespace Perspective.Wpf3D.Shapes
{
    /// <summary>
    /// 平面椭圆
    /// A 3D flat ellipse model.
    /// Default size of a side is 1.0.
    /// </summary>
    public class Ellipse3D : GeometryElement3D
    {
        #region Constructors

        /// <summary>
        /// Static constructor.
        /// </summary>
        static Ellipse3D()
        {
            BackMaterialProperty.OverrideMetadata(
                typeof(Ellipse3D),
                new PropertyMetadata(
                    null,
                    VisualPropertyChanged));
        }

        #endregion

        #region Properties

        #region SideCount 切片数
        /// <summary>
        /// 侧面数
        /// Gets or sets the model side count.
        /// Default value is 4. Minimum value is 3.
        /// </summary>
        public int SideCount
        {
            get { return (int)GetValue(SideCountProperty); }
            set { SetValue(SideCountProperty, value); }
        }

        /// <summary>
        /// Identifies the SideCount dependency property.
        /// </summary>
        public static readonly DependencyProperty SideCountProperty =
            DependencyProperty.Register(
                "SideCount",
                typeof(int),
                typeof(Ellipse3D),
                new PropertyMetadata(
                    360,
                    VisualPropertyChanged),
                SideCountValidateValue);

        /// <summary>
        /// Validation of the SideCount value.
        /// </summary>
        /// <param name="value">Value to test.</param>
        /// <returns>Boolean value.</returns>
        private static bool SideCountValidateValue(object value)
        {
            int i = (int)value;
            return i >= 3;
        }
        #endregion

        #region ParameterA 参数a

        /// <summary>
        /// 参数a
        /// Gets or sets the model side count.
        /// Default value is 1.0. Minimum value is 0.01.
        /// </summary>
        public double ParameterA
        {
            get { return (double)GetValue(ParameterAProperty); }
            set { SetValue(ParameterAProperty, value); }
        }

        /// <summary>
        /// Identifies the ParameterA dependency property.
        /// </summary>
        public static readonly DependencyProperty ParameterAProperty =
            DependencyProperty.Register(
                "ParameterA",
                typeof(double),
                typeof(Ellipse3D),
                new PropertyMetadata(
                    EllipseSculptor.DefaultParameterA,
                    VisualPropertyChanged),
                    ParameterAValidateValue);

        /// <summary>
        /// Validation of the ParameterA value.
        /// </summary>
        /// <param name="value">Value to test.</param>
        /// <returns>Boolean value.</returns>
        public static bool ParameterAValidateValue(object value)
        {
            double i = (double)value;
            return i >= 0.001;
        }

        #endregion

        #region ParameterB 高度

        /// <summary>
        /// 高度
        /// Gets or sets the model side count.
        /// Default value is 1.0. Minimum value is 0.01.
        /// </summary>
        public double ParameterB
        {
            get { return (double)GetValue(ParameterBProperty); }
            set { SetValue(ParameterBProperty, value); }
        }

        /// <summary>
        /// Identifies the ParameterB dependency property.
        /// </summary>
        public static readonly DependencyProperty ParameterBProperty =
            DependencyProperty.Register(
                "ParameterB",
                typeof(double),
                typeof(Ellipse3D),
                new PropertyMetadata(
                    EllipseSculptor.DefaultParameterB,
                    VisualPropertyChanged),
                    ParameterBValidateValue);

        /// <summary>
        /// Validation of the ParameterB value.
        /// </summary>
        /// <param name="value">Value to test.</param>
        /// <returns>Boolean value.</returns>
        public static bool ParameterBValidateValue(object value)
        {
            double i = (double)value;
            return i >= 0.001;
        }

        #endregion

        #endregion

        /// <summary>
        /// Called by UIElement3D.InvalidateModel() to update the 3D model.
        /// </summary>
        protected override void OnUpdateModel()
        {
            Sculptor = new EllipseSculptor(SideCount,ParameterA,ParameterB);
            base.OnUpdateModel();
        }
    }
}
